package org.uned.agonzalo16.bitacora.web.blog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.uned.agonzalo16.bitacora.dao.BlogContributionDao;
import org.uned.agonzalo16.bitacora.dao.BlogDao;
import org.uned.agonzalo16.bitacora.dao.UserDao;
import org.uned.agonzalo16.bitacora.domain.Blog;
import org.uned.agonzalo16.bitacora.domain.BlogContribution;
import org.uned.agonzalo16.bitacora.domain.User;
import org.uned.agonzalo16.bitacora.domain.UserType;

@RequestMapping("/admin/blog")
@Controller
public class BlogController {

	@Autowired
	private BlogDao blogDao;

	@Autowired
	private BlogContributionDao blogContributionDao;

	@Autowired
	private UserDao userDao;

	@RequestMapping(method = RequestMethod.GET, value = "/list")
	public String list(Model model) {
		List<Blog> blogs = blogDao.findAll();
		Collections.sort(blogs, new Comparator<Blog>() {
			@Override
			public int compare(Blog b1, Blog b2) {
				return b1.getName().compareToIgnoreCase(b2.getName());
			}
		});
		model.addAttribute("blogs", blogs);
		return "blog/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/beginCreate")
	public String beginCreate(Model model) {
		model.addAttribute("blog", new BlogForm());
		return "blog/create";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/create")
	public String create(@Valid @ModelAttribute("blog") BlogForm form, BindingResult result) {

		if (result.hasErrors()) {
			return "blog/create";
		}

		Blog blog = new Blog();
		blog.setCreationDate(new Date());
		blog.setDescription(form.getDescription());
		blog.setName(form.getName());

		blogDao.merge(blog);

		return "redirect:/admin/blog/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/show/{id}")
	public String show(@PathVariable("id") Long id, Model model) {
		model.addAttribute("blog", new BlogForm(blogDao.get(id)));
		return "blog/update";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/update")
	public String update(@Valid @ModelAttribute("blog") BlogForm form, BindingResult result) {

		if (result.hasErrors()) {
			return "blog/update";
		}

		Blog blog = blogDao.get(form.getId());
		blog.setDescription(form.getDescription());
		blog.setName(form.getName());

		blogDao.merge(blog);

		return "redirect:/admin/blog/list";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/delete/{id}")
	public String delete(@PathVariable("id") Long id) {
		blogDao.delete(id);
		return "redirect:/admin/blog/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/contributors/{id}")
	public String contributors(@PathVariable("id") Long id, Model model) {
		List<BlogContribution> currentContributors = blogContributionDao.findByBlog(blogDao.get(id));

		List<User> current = new ArrayList<User>();
		for (BlogContribution contributor : currentContributors) {
			current.add(contributor.getUser());
		}

		List<User> allUsers = userDao.findAll();
		List<User> contributors = new ArrayList<User>();
		for (User user : allUsers) {
			if (UserType.CONTRIBUTOR.getType().equals(user.getType()) && !current.contains(user)) {
				contributors.add(user);
			}
		}

		model.addAttribute("contributors", contributors);
		model.addAttribute("currentContributors", currentContributors);
		model.addAttribute("blogId", id);

		return "blog/contributors";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/contributors/add")
	public String addContributor(@ModelAttribute BlogContributorForm form) {

		BlogContribution bc = new BlogContribution();
		bc.setCreationDate(new Date());
		bc.setBlog(blogDao.get(form.getBlogId()));
		bc.setUser(userDao.get(form.getContributorId()));

		blogContributionDao.merge(bc);

		return "redirect:/admin/blog/contributors/" + form.getBlogId();
	}

	@RequestMapping(method = RequestMethod.POST, value = "/contributors/delete")
	public String deleteContributor(@ModelAttribute BlogContributorForm form) {

		blogContributionDao.delete(form.getContributorId());

		return "redirect:/admin/blog/contributors/" + form.getBlogId();
	}
}
